﻿#include "ConfigFile.hpp"
using namespace NAMESPACENAME;
ConfigFile ConfigFile::configFile;
ConfigFile::ConfigFile() :
	changed(false)
{
	size_t pathSize = 128;
	wchar_t* path = new wchar_t[2];
	do
	{
		delete[] path;
		pathSize <<= 1;
		path = new wchar_t[pathSize];
		GetModuleFileNameW(nullptr, path, pathSize);
	} while (GetLastError() == ERROR_INSUFFICIENT_BUFFER);
	fileName = path;
	delete[] path;
	fileName.pop_back();
	fileName.pop_back();
	fileName.pop_back();
	fileName += L"config";
}
bool ConfigFile::Read()
{
	HANDLE hFile = CreateFileW(fileName.c_str(), GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_HIDDEN, nullptr);
	if (auto ercd(GetLastError()); ercd)
	{
		if (ercd == ERROR_FILE_NOT_FOUND)
			return true;
		else
		{
			MessageBoxW(nullptr, L"打开config文件错误", L"Error!", MB_OK | MB_ICONERROR);
			exit(1);
		}
	}
	LARGE_INTEGER li;
	DWORD nSize;
	GetFileSizeEx(hFile, &li);
	char* pFile(new char[li.QuadPart + 2]);
	if (!ReadFile(hFile, pFile, li.QuadPart + 2, &nSize, nullptr))
	{
		MessageBoxW(nullptr, L"读取config文件错误", L"Error!", MB_OK | MB_ICONERROR);
		exit(1);
	}
	CloseHandle(hFile);
	pFile[li.QuadPart] = pFile[li.QuadPart + 1] = 0;
	unsigned __int64 index(0);
	std::string key, value;
	while (pFile[index])
	{
		while (pFile[index] != ':')
			key += pFile[index++];
		++index;
		while (pFile[index] != '\n' && pFile[index] != '\r')
			value += pFile[index++];
		if (pFile[index] == '\n')
			++index;
		configs.emplace(std::make_pair(key, value));
		key.clear();
		value.clear();
	}
	return true;
}
std::string ConfigFile::operator[](std::string key)const
{
	auto it = configs.find(key);
	if (it != configs.end())
		return it->second;
	return "";
}
void ConfigFile::Flush()const
{
	if (!changed)
		return;
	HANDLE hFile = CreateFileW(fileName.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, nullptr);
	if (auto ercd(GetLastError()); ercd)
		if (ercd != ERROR_ALREADY_EXISTS)
		{
			MessageBoxW(nullptr, L"打开config文件错误", L"Error!", MB_OK | MB_ICONERROR);
			exit(1);
		}
	std::string fileVar;
	DWORD nSize;
	for (auto& it : configs)
		fileVar += it.first + ':' + it.second + '\n';
	if (!WriteFile(hFile, fileVar.c_str(), fileVar.size(), &nSize, nullptr))
	{
		MessageBoxW(nullptr, L"写入config文件错误", L"Error!", MB_OK | MB_ICONERROR);
		exit(1);
	}
	CloseHandle(hFile);
}
void ConfigFile::SetValue(std::string key, std::string value)
{
	auto it = configs.find(key);
	if (it != configs.end())
		if (value == it->second)
			return;
		else
			it->second = value;
	else
		configs.emplace(std::make_pair(key, value));
	changed = true;
}
void ConfigFile::Remove(std::string key)
{
	auto it = configs.find(key);
	if (it != configs.end())
		configs.erase(it);
}
ConfigFile::~ConfigFile()
{
	Flush();
}